"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
//命名空间
var Reg;
(function (Reg) {
    //模板引擎正则匹配{{ ... }}
    Reg.templateRegExpDouble = /\{\{(.+?)\}\}/g;
    //模板引擎正则匹配[[ ... ]]
    Reg.templateRegExpOnce = /\[\[(.+?)\]\]/g;
    //大写字母匹配
    Reg.upCase = /^[A-Z]+$/g;
    //去除空格
    Reg.delSpace = /\s+/g;
})(Reg || (Reg = {}));
// let srt = "SdB";
// console.log(Reg.upCase.test(srt));
// console.log(srt.match(Reg.upCase));
var Validation;
(function (Validation) {
    var domModule = "";
})(Validation || (Validation = {}));
//逻辑开始
(function (win) {
    //Oject兼容性
    if (!Object.hasOwnProperty("is")) {
        Object.is = function (a, b) {
            if (a !== b) {
                return false;
            }
            else {
                return true;
            }
        };
    }
    //ajax
    var Ajax = (function () {
        function Ajax() {
        }
        //ajax逻辑
        Ajax.prototype.openAjax = function (method, url, data) {
            data = data || null;
            var responseStream = Rx.Observable.create(function (observer) {
                var xhr = new XMLHttpRequest;
                xhr.open(method, url + "?_=" + Math.random(), true);
                xhr.onload = function () {
                    observer.next({
                        dom: xhr.responseText,
                        url: url
                    });
                };
                xhr.onerror = function () {
                    console.error(url + "\u8BF7\u6C42\u5931\u8D25");
                };
                xhr.send(data);
            }).do(function (dom) {
                //写入缓存
                //TODO: 这里没完成
                // Ajax.cache.push(JSON.parse(`{"url": "${ dom.url }","dom": "${ dom.dom }"}`));
            });
            return responseStream;
        };
        //缓存
        Ajax.cache = [];
        return Ajax;
    }());
    //组件table
    var TzbTable = (function (_super) {
        __extends(TzbTable, _super);
        function TzbTable(TableData) {
            var _this = this;
            _super.call(this);
            this.TableData = TableData;
            this.headerDOM = document.createElement("thead");
            this.bodyDOM = document.createElement("tbody");
            this.tableDOM = document.createElement("table");
            this.cleanNode = false;
            this.trHash = "tr-" + Math.random().toString().replace(".", "");
            this.watchArray = [];
            this.bindOnceArray = [];
            this.clean = false;
            this.viewModel = {
                header: null,
                body: null,
                page: null,
                filter: null,
                //清空watch列表刷新表格
                _cleanWatch: function () {
                    _this.cleanNode = true;
                    _this.RegArray = null;
                    _this.bindOnce = null;
                    _this.watchArray = [];
                    _this.bindOnceArray = [];
                }
            };
            //运行控制器
            //默认加载TableData.htmlUrl
            if (TableData.htmlUrl) {
                this.obv = this.openAjax("GET", TableData.htmlUrl);
            }
            else if (TableData.htmlNodeList) {
                this.obv = this._createJsonHtml(TableData.htmlNodeList);
            }
            else {
                this.obv = "";
            }
            this._controller();
        }
        //写入DOM
        //TODO：这里需要修改
        TzbTable.prototype._domWriter = function (data) {
            document.querySelector(this.TableData.selector).appendChild(data);
        };
        //创建json dom
        TzbTable.prototype._createJsonHtml = function (data) {
            var tr = document.createElement("tr");
            data.forEach(function (d) {
                var td = document.createElement("td");
                td.innerHTML = d.data;
                Object.keys(d.attr).forEach(function (attr, index) {
                    if (attr === "className") {
                        td.setAttribute("class", d.attr[attr]);
                    }
                    else {
                        var newAttr = attr.split("").map(function (addStr) {
                            if (Reg.upCase.test(addStr)) {
                                return "-" + addStr.toLowerCase();
                            }
                            else {
                                return addStr;
                            }
                        });
                        td.setAttribute(newAttr.join(""), d.attr[attr]);
                    }
                    tr.appendChild(td);
                });
            });
            var readom = Math.random().toString().replace(".", "");
            var div = document.createElement("div");
            div.id = readom;
            div.appendChild(tr);
            return Rx.Observable.of({
                dom: div.innerHTML,
                url: readom
            });
        };
        //初始化样式选择器
        TzbTable.prototype._initHeaderStyleSekector = function () {
            if (!this.viewModel.header.classSelector) {
                this.viewModel.header.classSelector = ":";
            }
        };
        //完成thead构建
        TzbTable.prototype._tHead = function () {
            var _this = this;
            if (this.viewModel.header && this.viewModel.header.hasOwnProperty("data")) {
                var dom = this.viewModel.header.data.reduce(function (data, origin) {
                    var domNode = origin.split(_this.viewModel.header.classSelector);
                    return data + ("<th class=\"" + domNode[1] + "\">" + domNode[0] + "</th>");
                }, "");
                this.headerDOM.innerHTML = dom;
                this.tableDOM.appendChild(this.headerDOM);
            }
        };
        //完成脏检测列表构建
        TzbTable.prototype._creatWatchList = function (data) {
            var _this = this;
            //刚刚创建表格的逻辑
            if (!this.RegArray) {
                //创建翻页
                this._page();
                //获取模板数据
                //单项绑定
                console.log(data);
                var bindOnce = data.dom.match(Reg.templateRegExpOnce);
                this.bindOnce = bindOnce.map(function (data) {
                    return {
                        name: data,
                        object: data.replace("[[", "").replace("]]", "").replace(Reg.delSpace, "").split(".")
                    };
                });
                //双向绑定
                var RegArray = data.dom.match(Reg.templateRegExpDouble);
                this.RegArray = RegArray.map(function (data) {
                    //提取过滤器
                    var objectData = data;
                    var filter;
                    var filterPro;
                    if (data.indexOf("|") != -1) {
                        filterPro = data.split("|");
                        objectData = filterPro[0] + " }}";
                    }
                    if (_this.viewModel && _this.viewModel.filter && data.indexOf("|") != -1) {
                        filter = _this.viewModel.filter[filterPro[1].replace("}}", "").replace(Reg.delSpace, "")];
                    }
                    return {
                        filter: filter,
                        name: data,
                        object: objectData.replace("{{", "").replace("}}", "").replace(Reg.delSpace, "").split(".")
                    };
                });
                //创建watch列表
                if (this.viewModel.body && this.viewModel.body.hasOwnProperty("data")) {
                    this.viewModel.body.data.forEach(function (TableDataIndex) {
                        var listDataRegArray = [];
                        //从模板列表里填充数据
                        //双向绑定数据
                        _this.RegArray.forEach(function (RegArrayIndex) {
                            //重要需要把Object类型指向改变不然无法引用改变数据
                            RegArrayIndex = Object.create(RegArrayIndex);
                            if (Object.is("[object function]", Object.prototype.toString.call(RegArrayIndex.filter).toLowerCase())) {
                                RegArrayIndex.data = RegArrayIndex.filter(TzbTable.getObjectData(TableDataIndex, RegArrayIndex));
                            }
                            else {
                                RegArrayIndex.data = TzbTable.getObjectData(TableDataIndex, RegArrayIndex);
                            }
                            RegArrayIndex.hash = "td-" + Math.random().toString().replace(".", "");
                            listDataRegArray.push(RegArrayIndex);
                        });
                        _this.watchArray.push(listDataRegArray);
                        //单绑数据
                        var listDataBindOnce = [];
                        _this.bindOnce.forEach(function (bindOnceIndex) {
                            //重要需要把Object类型指向改变不然无法引用改变数据
                            bindOnceIndex = Object.create(bindOnceIndex);
                            bindOnceIndex.data = TzbTable.getObjectData(TableDataIndex, bindOnceIndex);
                            listDataBindOnce.push(bindOnceIndex);
                        });
                        _this.bindOnceArray.push(listDataBindOnce);
                    });
                }
            }
            else {
                //修改watch列表
                if (this.viewModel.body && this.viewModel.body.hasOwnProperty("data")) {
                    this.viewModel.body.data.forEach(function (TableDataIndex, dataIndex) {
                        //从模板列表里填充数据
                        _this.RegArray.forEach(function (RegArrayIndex, RegIndex) {
                            // 对比watch列表数据(只更新不一样的数据)
                            var newData = TzbTable.getObjectData(TableDataIndex, RegArrayIndex);
                            if (Object.is("[object function]", Object.prototype.toString.call(_this.watchArray[dataIndex][RegIndex].filter).toLowerCase())) {
                                newData = _this.watchArray[dataIndex][RegIndex].filter(newData);
                            }
                            if (!Object.is(_this.watchArray[dataIndex][RegIndex].data, newData)) {
                                _this.watchArray[dataIndex][RegIndex].data = newData;
                                document.querySelector("." + _this.watchArray[dataIndex][RegIndex].hash).innerHTML = newData;
                            }
                        });
                    });
                }
            }
        };
        //creatTbody
        TzbTable.prototype._creatTbable = function () {
            this._domWriter(this.tableDOM);
        };
        //构件tbody(这里只运行一次)
        TzbTable.prototype._tBody = function () {
            var _this = this;
            //判断是否要完全更新dom
            if (this.cleanNode) {
                this.cleanNode = false;
                Array.prototype.slice.call(document.querySelectorAll("." + this.trHash)).forEach(function (dom) {
                    dom.outerHTML = "";
                });
            }
            this.watchArray.forEach(function (data, indexWatch) {
                var dom = _this.template.dom;
                data.forEach(function (dataIndex, indexData) {
                    if (_this.bindOnceArray[indexWatch][indexData]) {
                        dom = dom.replace(_this.bindOnceArray[indexWatch][indexData].name, _this.bindOnceArray[indexWatch][indexData].data);
                    }
                    dom = dom.replace(dataIndex.name, "<td-data class=\"" + dataIndex.hash + "\">" + dataIndex.data + "</td-data>");
                });
                dom.replace("<tr>", "").replace("</tr>", "");
                var tr = document.createElement("tr");
                tr.className = _this.trHash;
                tr.innerHTML = dom;
                _this.bodyDOM.appendChild(tr);
            });
            this.tableDOM.appendChild(this.bodyDOM);
        };
        //脏检查
        TzbTable.prototype._differ = function (newValue) {
            this._creatWatchList(this.template);
        };
        //控制器绑定
        TzbTable.prototype._controller = function () {
            var _this = this;
            var _that = this;
            //双向绑定设置
            Object.defineProperty(this.viewModel, "header", {
                set: function (newValue) {
                    this._newValueHeader = newValue;
                    //写入头部(头部不做hash双向绑定)
                    if (_that.viewModel.header && _that.viewModel.header.data) {
                        _that._initHeaderStyleSekector();
                        _that._tHead();
                        _that._creatTbable();
                    }
                },
                get: function () {
                    return this._newValueHeader;
                }
            });
            //观察模板加载完毕
            _that.obv.subscribe(function (data) {
                Object.defineProperty(_this.viewModel, "body", {
                    set: function (newValue) {
                        this._newValueBody = newValue;
                        //加载HTML完成watch列表
                        if (_that.watchArray.length === 0) {
                            //写入body
                            _that.template = data;
                            _that._creatWatchList(data);
                            _that._tBody();
                        }
                        else {
                            //运行脏检测
                            _that._differ(newValue);
                        }
                    },
                    get: function () {
                        return this._newValueBody;
                    }
                });
            });
            //分页隐藏显示
            Object.defineProperty(this.viewModel, "_pageShow", {
                set: function (newValue) {
                    this._newPageShow = newValue;
                    if (newValue) {
                        document.querySelector(_that.TableData.selector + "-page").style.display = "block";
                    }
                    else {
                        document.querySelector(_that.TableData.selector + "-page").style.display = "none";
                    }
                },
                get: function () {
                    return this._newPageShow;
                }
            });
            //增加viewModel
            this.TableData.controller(this.viewModel);
        };
        //翻页
        TzbTable.prototype._page = function () {
            var _this = this;
            var dom = document.querySelector(this.TableData.selector + "-page");
            dom.innerHTML = "\n                <button id=\"up-page-" + this.TableData.selector + "\">\u4E0A\u7FFB\u9875</botton>\n                <button id=\"down-page-" + this.TableData.selector + "\">\u4E0B\u7FFB\u9875</botton>\n            ";
            document.querySelector("#up-page-" + this.TableData.selector).onclick = function () {
                if (_this.viewModel && _this.viewModel.page && _this.viewModel.page.pageUp) {
                    _this.viewModel.page.pageUp(_this.viewModel);
                }
            };
            document.querySelector("#down-page-" + this.TableData.selector).onclick = function () {
                if (_this.viewModel && _this.viewModel.page && _this.viewModel.page.pageDown) {
                    _this.viewModel.page.pageDown(_this.viewModel);
                }
            };
        };
        //根据数组获取对象索引值
        TzbTable.getObjectData = function (obj, pro) {
            var cacheObj;
            pro.object.forEach(function (data) {
                if (!cacheObj) {
                    cacheObj = obj[data];
                }
                else {
                    if (Object.is("[object object]", Object.prototype.toString.call(cacheObj).toLowerCase())) {
                        cacheObj = cacheObj[data];
                    }
                }
            });
            //深度克隆
            return cacheObj;
        };
        return TzbTable;
    }(Ajax));
    ;
    win.TzbTable = TzbTable;
})(Function("return this")());
